#pragma once

#include"Socket.hpp"
#include<memory>
#include"InetAddr.hpp"
#include<unistd.h>
#include<signal.h>

//只负责进行IO
class TcpServer
{
public:
    TcpServer(int port)
    :_port(port),_listensocket(std::make_unique<TcpSocket>())
    {
        _listensocket->BuildSocketMetod(_port);
    }
    //处理请求
    void HandlerRequest(std::shared_ptr<Socket>sockfd,InetAddr addr)
    {
        //长服务
        std::string inbuffer;
        while(true)
        {
            ssize_t n=sockfd->Recv(&inbuffer);
            if(n>0)
            {
                //都必须和协议有关！！！1
                //1.你怎么知道inbuff里面至少有一个完整的报文？
                //2.如何把这个报文，拿给上层处理？
                //3，上层拿到了一个报文，该如何处理呢？
                //如何自定义协议？？？？--->如何序列反序列化。
                LOG(LogLevel::DEBUG)<<add.ToString()<<" say:"<<inbuffer;
                  sockfd->Send(inbuffer);
            }
            else if(n==0)
            {
                LOG(LogLevel::DEBUG)<<addr.ToString()<<" quit!";
                sockfd->Close();
                break;
            }
            else
            {
                LOG(LogLevel::ERROR)<<addr.ToString()<<" recv error,quit!";
              
                break;
            }

          
        }
        sockfd->Close();
        
    }
    void Run()
    {
        signal(SIGCHLD,SIG_IGN);
        while(true)
        {
            //得到一个fd,再得到一个客户端地址clientaddr
            InetAddr addr;
            auto sockfd=_listensocket->Accept(&addr);
            if(sockfd==nullptr) continue;
            LOG(LogLevel::INFO)<<"Get a new client:"<<addr.ToString();
            //获取一个新连接，和客户端进行通信

            if(fork()==0)
            {
                _listensocket->Close();//只是将文件描述符计数改变
                //子进程进行IO处理
                HandlerRequest(sockfd,addr);
                exit(0);
                
            }
            sockfd->Close();

        }
    }

    ~TcpServer()
    {}

private:
    int _port;
    std::unique_ptr<Socket> _listensocket;
}
